﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common.UI.EM.Views.Interfaces;
using Common.UI.EM.Views;
using Common.Model;
using Common.ServiceLogic;
using System.Data.Objects.DataClasses;

namespace Common.UI.EM
{
    public class GenericEntityController<S, E, C, EV> : GenericController
        where S : IGenericEntityManagerServiceLogic<E, C, EV>, new()
        where E : IObjectWithChangeTracker, new()
        where C : CriteriaEntity, new()
        where EV : ViewEntity
    {
        public virtual String Title
        {
            get { return string.Empty; }
        }

        public IEntityPresentationModel<S, E, C, EV> EntityPresentationModel
        {
            get;
            set;
        }


        public IEntityManagerView EntityManagerView
        {
            get;
            set;
        }


        public override void Run()
        {
            this.CreatePresentationModels();

            this.CreateEntityManagerView();

            this.RegisterEventHandlers();

            this.InitializePresentationModels();

            this.RegisterEntityManagerView();
        }

        public void RunInAdd()
        {
            this.Run();

            this.ShowDetail(DetailMode.Add, null);
            this.EntityPresentationModel.ShowDetail(DetailMode.Add, null);
        }
       
        private void CreatePresentationModels()
        {
            this.CreateEntityPresentationModel();
        }

        protected virtual void CreateEntityPresentationModel()
        {
            this.EntityPresentationModel = new EntityPresentationModel<S, E, C, EV>(this.CreateFilterView(), this.CreateListView(), this.CreateDetailView());
        }


        protected IFilterView CreateFilterView()
        {
            var dv = new FilterView();
            dv.ContentControl = this.CreateFilterDataView();
            return dv;
        }

        protected virtual FilterDataView CreateFilterDataView()
        {
            return new FilterDataView();
        }


        protected IDetailView CreateDetailView()
        {
            var dv = new DetailView();
            dv.ContentControl = this.CreateDetailDataView();
            return dv;
        }


        private void UpdateDetailDataView()
        {
            this.EntityPresentationModel.DetailView.ContentControl = this.CreateDetailDataView();
        }

        protected virtual DetailDataView CreateDetailDataView()
        {
            return new DetailDataView();
        }

    
        protected ListView CreateListView()
        {
            return new ListView();
        }


        private void CreateEntityManagerView()
        {
            EntityManagerView = new EntityManagerView(this.EntityPresentationModel.FilterView, this.EntityPresentationModel.ListView, this.EntityPresentationModel.DetailView);
        }

        private void RegisterEventHandlers()
        {
            this.EntityPresentationModel.SearchCalled += new SearchCalledEventHandler(FilterPresentationModel_SearchCalled);

            this.EntityPresentationModel.AddCalled += new AddCalledEventHandler(ListPresentationModel_AddCalled);
            this.EntityPresentationModel.ModifyCalled += new ModifyCalledEventHandler(ListPresentationModel_ModifyCalled);
            this.EntityPresentationModel.ViewCalled += new ViewCalledEventHandler(ListPresentationModel_ViewCalled);
            this.EntityPresentationModel.DeleteCalled += new DeleteCalledEventHandler(ListPresentationModel_DeleteCalled);

            this.EntityPresentationModel.SaveCalled += new SaveCalledEventHandler(DetailPresentationModel_SaveCalled);
            this.EntityPresentationModel.CancelCalled += new CancelCalledEventHandler(DetailPresentationModel_CancelCalled);

            this.RegisterCustomEventHandlers();
        }

        protected virtual void RegisterCustomEventHandlers()
        {
        }

        
        void FilterPresentationModel_SearchCalled(object sender, Microsoft.Practices.Composite.Events.DataEventArgs<CriteriaEntity> e)
        {
            EntityManagerView.ShowFilter();
        }

        
        void ListPresentationModel_ViewCalled(object sender, Microsoft.Practices.Composite.Events.DataEventArgs<ViewEntity> e)
        {
            this.ShowDetail(DetailMode.View, e.Value);
        }

        void ListPresentationModel_ModifyCalled(object sender, Microsoft.Practices.Composite.Events.DataEventArgs<ViewEntity> e)
        {
            this.ShowDetail(DetailMode.Modify, e.Value);
        }

        void ListPresentationModel_DeleteCalled(object sender, Microsoft.Practices.Composite.Events.DataEventArgs<ViewEntity> e)
        {
            EntityManagerView.ShowFilter();
           
        }

        void ListPresentationModel_AddCalled(object sender, EventArgs e)
        {
            this.ShowDetail(DetailMode.Add, null);
        }


        private void ShowDetail(DetailMode detailMode, ViewEntity viewEntity)
        {
            UpdateDetailDataView();
            EntityManagerView.ShowDetail();
        }


        void DetailPresentationModel_CancelCalled(object sender, EventArgs e)
        {
            EntityManagerView.ShowList();
        }

        void DetailPresentationModel_SaveCalled(object sender, EventArgs e)
        {
            EntityManagerView.ShowFilter();
        }


        private void InitializePresentationModels()
        {
            //FILTER
            this.EntityPresentationModel.LoadCriteria(new C());
            this.AddColumnDefinitions();

            //LIST
            this.EntityPresentationModel.AllowAdd = Common.Security.Authorization.CanExecuteAdd(this.GetFullName());
            this.EntityPresentationModel.AllowDelete = Common.Security.Authorization.CanExecuteDelete(this.GetFullName());
            this.EntityPresentationModel.AllowModify = Common.Security.Authorization.CanExecuteModify(this.GetFullName());
            this.EntityPresentationModel.AllowView = Common.Security.Authorization.CanExecuteView(this.GetFullName());

        }

        protected virtual void AddColumnDefinitions()
        {
        }


        private void RegisterEntityManagerView()
        {
            MainView.View.RegisterView(this.Title, this.EntityManagerView);
        }

    }
}
